/* Copyright (c) 2011-2013 ISP RAS, Moscow. For more information please write to
 
      mermakov@ispras.ru
      svartanov@ispras.ru

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package ru.ispras.coffeemachine.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.channels.FileChannel;

/**
 * Utility functions for file writing
 * 
 * @author Mikhail Ermakov (mermakov@ispras.ru)
 * @version 1.2.0
 * @since 2011-09-12
 */
public class Util {

	/**
	 * Deletes target file or directory with all its contents.
	 * @param file target file or directory
	 * @return <code>true</code> if all files were deleted successfully, <code>false</code> otherwise
	 * @throws SecurityException
	 */
	public static boolean deleteFileRecursive(File file) throws SecurityException {

		boolean result = true;
		if (file != null) {
			if (file.isDirectory()) {
				for (File subfile : file.listFiles()) {
					result = result && deleteFileRecursive(subfile);
				}
			}
			result = result && file.delete();
		} else {
			return false;
		}
		return result;
	}

	/**
	 * Deletes target file or directory with all its contents.
	 * @param file path to target file or directory
	 * @return <code>true</code> if all files were deleted successfully, <code>false</code> otherwise
	 * @throws SecurityException
	 */
	public static boolean deleteFileRecursive(String fileName) {

		try {
			return deleteFileRecursive(new File(fileName));
		} catch (SecurityException e) {
			return false;
		}
	}

	/**
	 * Copies source file into target file.
	 * @param source path to source file
	 * @param dest path to target file
	 * @param rewrite specify <code>true</code> to allow rewriting existing files
	 * @throws IOException
	 */
	public static void copyFile(String source, String dest, boolean rewrite) throws IOException {

		File sourceFile = new File(source);
		File destFile = new File(dest);
		if (!destFile.exists()) {
			destFile.createNewFile();
		} else if (!rewrite) {
			return;
		}

		FileChannel sourceChannel = null;
		FileChannel destChannel = null;

		try {
			sourceChannel = new FileInputStream(sourceFile).getChannel();
			destChannel = new FileOutputStream(destFile).getChannel();
			destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
		} finally {
			if (sourceChannel != null) {
				sourceChannel.close();
			}
			if (destChannel != null) {
				destChannel.close();
			}
		}
	}

	/**
	 * Copies source file into target file. Existing files are not overwritten.
	 * @param source path to source file
	 * @param dest path to target file
	 * @throws IOException
	 */
	public static void copyFile(String source, String dest) throws IOException {

		copyFile(source, dest, false);
	}

	/**
	 * Creates a directory with specified path.
	 * @param path target directory path
	 * @throws IOException
	 */
	public static void makeDir(String path) throws IOException {
		
		File dir = new File(path);
		if (!dir.exists()) {
			if (!dir.mkdir()) {
				throw new IOException("Cannot create dir " + path);
			}
		}
	}
	
	/**
	 * Writes specified text into target file
	 * @param fileName target file path
	 * @param text text to write
	 * @throws IOException
	 */
	public static void write(String fileName, String text) throws IOException
	{
		try
		{
			FileWriter writer = new FileWriter(fileName);
			writer.write(text);
			writer.close();
		}
		catch (IOException e)
		{
			Logger.error("cannot write to the file " + fileName);
		}
	}

	/**
	 * Writes specified byte sequence into target file
	 * @param fileName target file path
	 * @param bytes byte sequence to write
	 * @throws IOException
	 */
	public static void write(String fileName, byte[] bytes) throws IOException
	{
		try
		{
			FileOutputStream writer = new FileOutputStream(fileName);
			writer.write(bytes);
			writer.close();
		}
		catch (IOException e)
		{
			Logger.error("cannot write to the file " + fileName);
		}
	}
}
